package com.gzhryc.shared_device.oem.micro.api.controllers.xcx.v1;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.IDTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.config.PropertyTools;
import com.gzhryc.common.data.ValidateTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.gps.GPSDistance;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.common.secruity.VerifyCodeTools;
import com.gzhryc.common.sms.SmsService;
import com.gzhryc.dictionary.dao.db.CountryArea;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.base.models.VerifyCodeData;
import com.gzhryc.shared_device.common.CountryAreaUtils;
import com.gzhryc.shared_device.common.payment.dao.db.AppConfig;
import com.gzhryc.shared_device.common.payment.services.AppConfigService;
import com.gzhryc.shared_device.oem.code.business.dao.db.PlaceRecommendation;
import com.gzhryc.shared_device.oem.code.business.services.PlaceRecommendationService;
import com.gzhryc.shared_device.oem.code.config.dao.db.AgreementDocument;
import com.gzhryc.shared_device.oem.code.config.dao.db.AppResourcePreload;
import com.gzhryc.shared_device.oem.code.config.services.AgreementDocumentService;
import com.gzhryc.shared_device.oem.code.config.services.AppResourcePreloadService;
import com.gzhryc.shared_device.oem.code.config.services.dto.AppResourcePreloadSearch;
import com.gzhryc.shared_device.oem.code.member.LoginMember;
import com.gzhryc.shared_device.oem.code.member.LoginMemberSessionManager;
import com.gzhryc.shared_device.oem.code.place.dao.db.PlacePhysicalStore;
import com.gzhryc.shared_device.oem.code.place.services.PlacePhysicalStoreService;
import com.gzhryc.shared_device.oem.code.user.dao.db.User;
import com.gzhryc.shared_device.oem.code.user.services.UserService;
import com.gzhryc.shared_device.oem.micro.api.MicroConstants;
import com.gzhryc.shared_device.oem.micro.api.PlaceGPSServiceManager;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.ClientAPICodeConstants;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.DefaultResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.ResourcePreloadRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.ResourcePreloadResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.AgreementGetRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.AgreementGetResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.AppConfigRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.AppConfigResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.ChinaAreaJsonResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.NearbyPlaceListRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.NearbyPlaceListResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.PlaceRecommendationRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.SendSMSRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.SendSMSResponse;

public class CommonController {

    static Logger log = Logger.getLogger(CommonController.class);

    @Route("/xcx/v1/common/china/area/select.data")
    public ChinaAreaJsonResponse select(HttpServletRequest request, HttpServletResponse response){
        ChinaAreaJsonResponse apiResp = new ChinaAreaJsonResponse(ClientAPICodeConstants.NULL_DATA, "暂无数据");
        List<CountryArea> data = CountryAreaUtils.getCountryAreaList();
        if(data != null && data.size() > 0){
            apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
            apiResp.getBody().setData(new HashMap<>());
            for(CountryArea province : data){
                Map<String,List<String>> item = new HashMap<>();
                if(province.getChildren() != null && province.getChildren().size() > 0){
                    for(CountryArea city : province.getChildren()){
                        List<String> cc = new ArrayList<>();
                        if(city.getChildren() != null && city.getChildren().size() > 0){
                            for(CountryArea cityArea : city.getChildren()) {
                                cc.add(cityArea.getName());
                            }
                        }
                        item.put(city.getName(),cc);
                    }
                }
                apiResp.getBody().getData().put(province.getName(),item);
            }
        }
        return apiResp;
    }

    @Route("/xcx/v1/common/agreement/get.data")
    public AgreementGetResponse getAgreement(HttpServletRequest request){
        AgreementGetResponse apiResp = new AgreementGetResponse(ClientAPICodeConstants.NULL_DATA,"暂无数据");
        AgreementGetRequest apiReq = WebUtils.getJsonRequest(request, AgreementGetRequest.class);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getCode()) && StringTools.isNotBlank(apiReq.getBody().getAppId())) {
            AgreementDocument agreementDocument = AgreementDocumentService.self().getByKeys(apiReq.getBody().getCode(),apiReq.getBody().getAppId());
            if(agreementDocument != null && StringTools.isNotBlank(agreementDocument.getContent())){
                apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                apiResp.getBody().setTitle(agreementDocument.getTitle());
                apiResp.getBody().setContent(agreementDocument.getContent());
            }
        }
        return apiResp;
    }

    /**
     * 获取应用的配置
     * @param request
     * @return
     */
    @Route("/xcx/v1/common/app_config/get.data")
    public AppConfigResponse getConfig(HttpServletRequest request){
        AppConfigResponse apiResp = new AppConfigResponse(ClientAPICodeConstants.NULL_DATA,"暂无数据");
        AppConfigRequest apiReq = WebUtils.getJsonRequest(request, AppConfigRequest.class);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getAppId()) && apiReq.getBody().getType() != null) {
            AppConfig appConfig = AppConfigService.self().getByKeys(apiReq.getBody().getAppId(),apiReq.getBody().getType());
            if(appConfig != null){
                apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                apiResp.getBody().setServerPhone(appConfig.getServerPhone());
            }
        }
        return apiResp;
    }

    /**
     * 附近的网点
     * @param request
     * @return
     */
    @Route("/xcx/v1/common/nearby_place/list.data")
    public NearbyPlaceListResponse findNearbyPlace(HttpServletRequest request){
        NearbyPlaceListResponse apiResp = new NearbyPlaceListResponse(ClientAPICodeConstants.NULL_DATA,"暂无数据");
        NearbyPlaceListRequest apiReq = WebUtils.getJsonRequest(request, NearbyPlaceListRequest.class);
        if (apiReq != null && apiReq.getBody().getLatitude() != null && apiReq.getBody().getLongitude() != null) {
            Double limitDistance = 1000D;       //限制1千M
            if(StringTools.isNotBlank(apiReq.getBody().getBusinessType())){

            }else{
                List<GPSDistance> gpsDistanceList = PlaceGPSServiceManager.self().getLocationService().findByGPS(apiReq.getBody().getLatitude()
                        ,apiReq.getBody().getLongitude(),limitDistance,apiReq.getBody().getLimit());
                if(gpsDistanceList != null && gpsDistanceList.size() > 0){
                    List<Long> placeIds = new ArrayList<>();
                    for(GPSDistance gpsDistance : gpsDistanceList){
                        placeIds.add(gpsDistance.getId());
                    }

                    List<PlacePhysicalStore> placePhysicalStoreList = PlacePhysicalStoreService.self().findByIds(placeIds);

                    if(placePhysicalStoreList != null && placePhysicalStoreList.size() > 0) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setItems(new ArrayList<>());

                        for (GPSDistance gpsDistance : gpsDistanceList) {
                            PlacePhysicalStore physicalStore = null;
                            for (PlacePhysicalStore temp : placePhysicalStoreList) {
                                if (temp.getId().equals(gpsDistance.getId())) {
                                    physicalStore = temp;
                                    break;
                                }
                            }

                            if (physicalStore != null) {
                                NearbyPlaceListResponse.Item item = new NearbyPlaceListResponse.Item();
                                item.setPlaceId(physicalStore.getId());
                                item.setPlaceName(physicalStore.getName());
                                item.setProvince(physicalStore.getProvince());
                                item.setAddress(physicalStore.getAddress());
                                item.setRouteInfo(physicalStore.getRouteInfo());
                                item.setContactPhone(physicalStore.getContactPhone());      //联系电话
                                if (physicalStore.getOpenTime() != null && physicalStore.getCloseTime() != null) {
                                    item.setWorkTimes(DateTools.changeHHmm(physicalStore.getOpenTime()) + "-" + DateTools.changeHHmm(physicalStore.getCloseTime()));
                                }
                                item.setLongitude(physicalStore.getLongitude());
                                item.setLatitude(physicalStore.getLatitude());
                                item.setDistance(gpsDistance.getDistance());
                                apiResp.getBody().getItems().add(item);
                            }
                        }
                    }
                }
            }
        }
        return apiResp;
    }

    @Route("/xcx/v1/common/resource/preload.data")
    public ResourcePreloadResponse resourcePreload(HttpServletRequest request){
        ResourcePreloadResponse apiResp = new ResourcePreloadResponse(ClientAPICodeConstants.NULL_DATA,"暂无数据");
        ResourcePreloadRequest apiReq = WebUtils.getJsonRequest(request, ResourcePreloadRequest.class);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getAppId())) {
            AppResourcePreloadSearch search = new AppResourcePreloadSearch();
            search.setAppId(apiReq.getBody().getAppId());

            List<AppResourcePreload> appPreloadList = AppResourcePreloadService.self().findBySearch(search,1, MicroConstants.PAGE_LIMIT);
            if(appPreloadList != null && appPreloadList.size() > 0){
                apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                apiResp.getBody().setItems(new ArrayList<>());
                String resDomain = PropertyTools.get().getString("resDomain");
                for(AppResourcePreload appPreload : appPreloadList){
                    ResourcePreloadResponse.Item item = new ResourcePreloadResponse.Item();
                    item.setId(appPreload.getId());
                    item.setType(appPreload.getType());
                    item.setPath(WebUtils.setHttpDomain(resDomain,appPreload.getPath()));
                    apiResp.getBody().getItems().add(item);
                }
            }
        }
        return apiResp;
    }

    @Route(value = "/xcx/v1/common/sendSMS.do")
    public SendSMSResponse sendSMS(HttpServletRequest request) {
        SendSMSResponse apiResp = new SendSMSResponse(ClientAPICodeConstants.EXECUTE_ERROR);
        SendSMSRequest apiReq = WebUtils.getJsonRequest(request, SendSMSRequest.class);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getPhone()) && StringTools.isNotBlank(apiReq.getBody().getCode())
                && StringTools.isNotBlank(apiReq.getBody().getT()) && StringTools.isNotBlank(apiReq.getBody().getPt())) {
            User user = UserService.self().getByPhone(apiReq.getBody().getPhone());
            if(user != null) {
                String code = apiReq.getBody().getCode();
                String t = apiReq.getBody().getT();
                VerifyCodeData verifyCodeData = LoginMemberSessionManager.self().getVerifyCode(t);
                if (verifyCodeData != null && verifyCodeData.getCode().equals(code.toUpperCase())) {
                    String phoneValid = IDTools.getRandomNumberStr(6);
                    VerifyCodeData codeData = new VerifyCodeData();
                    codeData.setCode(phoneValid);
                    codeData.setCreateDate(new Date());
                    String token = user.getPhone() + "_" + apiReq.getBody().getPt();
                    codeData.setToken(token);

                    if(LoginMemberSessionManager.self().setVerifyCodeSession(codeData)) {
                        String smsSign = "共享充电";
                        if(SmsService.synSendPhoneVerifyCode(user.getPhone(),codeData.getCode(),smsSign)){
                            apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                            LoginMemberSessionManager.self().removeVerifyCode(t);
                        }else{
                            log.error("发送短信失败，手机号：{{0}}",user.getPhone());
                        }
                    }else{
                        log.error("缓存手机号验证码失败：内容：{{0:json}}",codeData);
                    }
                }else{
                    log.error("图片验证码错误，数据：{{0:json}}",verifyCodeData);
                    apiResp.setMsg("图片验证码错误");
                }
            }else{
                log.error("未找到用户，手机号：" + apiReq.getBody().getPhone());
            }
        }
        return apiResp;
    }

    @Route(value = "/xcx/v1/common/verifyCode.jpeg")
    public void verifyCode(HttpServletRequest request, HttpServletResponse response) {
        Integer width = WebUtils.getInteger(request, "w", 250);
        Integer height = WebUtils.getInteger(request, "h", 50);
        String t = WebUtils.getString(request, "t");
        if(StringTools.isNotBlank(t) && t.length() > 10) {
            VerifyCodeTools.VerifyCode verifyCode = VerifyCodeTools.createImg(width, height, 5);
            VerifyCodeData codeData = new VerifyCodeData();
            codeData.setCode(verifyCode.getCode());
            codeData.setCreateDate(new Date());
            codeData.setToken(t);
            LoginMemberSessionManager.self().setVerifyCodeSession(codeData);
            WebUtils.exportJPEG(response, verifyCode.getImg());
        }
    }

    @Route(value = { "/xcx/v1/common/place_recommendation/apply.do" })
    public DefaultResponse applyPlaceRecommendation(HttpServletRequest request) {
        DefaultResponse apiResp = new DefaultResponse(ClientAPICodeConstants.EXECUTE_ERROR, "推荐场地失败，请稍后再试！");
        PlaceRecommendationRequest apiReq = WebUtils.getJsonRequest(request, PlaceRecommendationRequest.class);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getName()) && StringTools.isNotBlank(apiReq.getBody().getPhone())
            && StringTools.isNotBlank(apiReq.getBody().getProvince()) && StringTools.isNotBlank(apiReq.getBody().getCity())
            && StringTools.isNotBlank(apiReq.getBody().getCityArea())) {
            if(!ValidateTools.isPhone(apiReq.getBody().getPhone())){
                apiResp.setMsg("请填写正确的手机号");
                return apiResp;
            }

            if(!StringTools.isChinese(apiReq.getBody().getName())){
                apiResp.setMsg("请填写中文姓名");
                return apiResp;
            }

            String note = apiReq.getBody().getNote();
            if(StringTools.isNotBlank(note)) {
                //过滤HTML标签
                note = ValidateTools.delHTMLTag(note);
            }

            LoginMember member = WebUtils.getAttribute(request, MicroConstants.ATTR_LOGIN_MEMBER, LoginMember.class);
            if (member != null) {
                PlaceRecommendation placeRecommendation = new PlaceRecommendation();
                placeRecommendation.setMemberId(member.getId());
                placeRecommendation.setMemberName(member.getNickname());
                placeRecommendation.setMemberPhone(member.getPhone());
                placeRecommendation.setName(apiReq.getBody().getName());
                placeRecommendation.setPhone(apiReq.getBody().getPhone());
                placeRecommendation.setProvince(apiReq.getBody().getProvince());
                placeRecommendation.setCity(apiReq.getBody().getCity());
                placeRecommendation.setCityArea(apiReq.getBody().getCityArea());
                placeRecommendation.setNote(note);

                try {
                    if (PlaceRecommendationService.self().add(placeRecommendation)) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                    }
                } catch (LogicException e) {
                    apiResp.setMsg(e.getMessage());
                }
            }
        }
        return apiResp;
    }
}
